package com.yhtx.easy.handler;

import com.yhtx.easy.annotation.Thumbnail;
import org.springframework.stereotype.Component;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 图片处理字段切面实现
 * @Author ZhuoXiaoYa
 * @Date 2025/5/23
 **/
@Aspect
@Component
public class ThumbnailAspect {

    /**
     * 拦截所有返回值为 Map 或自定义对象的方法
     */
    @Around("execution(* com.yhtx..*.*(..)) && @annotation(com.yhtx.easy.annotation.ThumbnailMark)")
    public Object processThumbnail(ProceedingJoinPoint joinPoint) throws Throwable {
        // 执行原方法
        Object result = joinPoint.proceed();
        if (result == null) {
            return null;
        }
        // 处理 Map 类型的返回值
        if (result instanceof Map) {
            return processMap((Map<?, ?>) result);
        }
        // 处理自定义对象类型的返回值
        return processObject(result);
    }

    /**
     * 处理 Map 类型的返回值
     */
    private Map<?, ?> processMap(Map<?, ?> originalMap) {
        Map<Object, Object> resultMap = new HashMap<>(originalMap);
        originalMap.forEach((key, value) -> {
            if (value instanceof String) {
                // 检查是否有 Thumbnail 注解的字段需要处理
                Optional<Field> thumbnailField = findThumbnailField(key.toString(), originalMap);
                if (thumbnailField.isPresent()) {
                    try {
                        Thumbnail annotation = thumbnailField.get().getAnnotation(Thumbnail.class);
                        String originalValue = (String) originalMap.get(key);
                        String processedValue = processThumbnailValue(originalValue, annotation);
                        resultMap.put(key, processedValue);
                    } catch (Exception e) {
                        // 处理异常
                    }
                }
            }
        });
        return resultMap;
    }

    /**
     * 处理自定义对象类型的返回值
     */
    private Object processObject(Object object) {
        try {
            if (object == null) {
                return null;
            }
            // 检查对象是否是 List 类型
            if (object instanceof List) {
                List<?> list = (List<?>) object;
                List result = new ArrayList<>(list.size());
                for (int i = 0; i < list.size(); i++) {
                    Object element = list.get(i);
                    result.add(processObject(element));
                }
                return list;
            }
            // 获取对象的所有字段
            Field[] fields = object.getClass().getDeclaredFields();
            for (Field field : fields) {
                // 检查字段是否有 Thumbnail 注解
                if (field.isAnnotationPresent(Thumbnail.class)) {
                    Thumbnail annotation = field.getAnnotation(Thumbnail.class);
                    // 设置字段可访问
                    field.setAccessible(true);
                    // 获取字段值
                    Object value = field.get(object);
                    if (value instanceof String) {
                        String processedValue = processThumbnailValue((String) value, annotation);
                        field.set(object, processedValue);
                    }
                }
                // 递归处理嵌套对象
                field.setAccessible(true);
                Object fieldValue = field.get(object);
                if (fieldValue != null && !field.getType().isPrimitive() && !field.getType().isEnum()
                        && !(fieldValue instanceof String) && !(fieldValue instanceof Number)
                        && !(fieldValue instanceof Boolean) && !(fieldValue instanceof Character)) {
                    // 递归调用 processObject 处理嵌套对象
                    processObject(fieldValue);
                }
            }
            return object;
        } catch (Exception e) {
            throw new RuntimeException("处理缩略图注解时出错", e);
        }
    }

    /**
     * 查找 Map 中是否有被 Thumbnail 注解标记的字段
     */
    private Optional<Field> findThumbnailField(String key, Map<?, ?> map) {
        // 这里简化处理，实际应用中可能需要更复杂的逻辑来匹配字段名
        // 或者可以在注解中添加 key 属性来明确指定
        // 示例：假设 key 就是字段名
        try {
            // 这里只是示例，实际应该从类中查找字段
            // 更合理的做法是使用反射获取返回对象的类类型
            return Arrays.stream(map.keySet().toArray())
                    .filter(k -> k.toString().equals(key))
                    .findFirst()
                    .map(k -> {
                        try {
                            // 这里需要知道具体的类类型，示例中无法获取，所以需要改进
                            // 实际应用中应该从返回对象的类中查找字段
                            return null; // 实际实现需要替换这部分
                        } catch (Exception e) {
                            return null;
                        }
                    });
        } catch (Exception e) {
            return Optional.empty();
        }
    }

    /**
     * 处理缩略图值
     * 目前只处理一下阿里云的图片处理后缀
     */
    private String processThumbnailValue(String originalValue, Thumbnail annotation) {
        if (originalValue == null || originalValue.isEmpty() || originalValue.contains("?x-oss-process=style/")) {
            return originalValue;
        }
        return originalValue + "?x-oss-process=style/" + annotation.styleName();
    }
}
